import 'package:easy_chat_app/commons/GlobalStatus.dart';
import 'package:easy_chat_app/commons/db/repository/LocalConversationRepository.dart';
import 'package:easy_chat_app/commons/db/service/LocalConversationService.dart';
import 'package:easy_chat_app/commons/db/service/LocalMessageService.dart';
import 'package:easy_chat_app/commons/model/AppUserDetail.dart';
import 'package:easy_chat_app/commons/model/GetContactsListItem.dart';
import 'package:easy_chat_app/commons/model/GetUserChatGroupInfoListItem.dart';
import 'package:easy_chat_app/commons/utils/HttpUtils.dart';
import 'package:easy_chat_app/commons/utils/RouteUtils.dart';
import 'package:easy_chat_app/commons/utils/StringUtils.dart';
import 'package:easy_chat_app/commons/widget/ChatGroupHeadPortrait.dart';
import 'package:easy_chat_app/commons/widget/UserHeadPortrait.dart';
import 'package:easy_chat_app/mobile/page/MobileChatPage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:logger/logger.dart';
import 'package:provider/provider.dart';

class MobileMessagePageData {
  List<LocalConversation> localConversationList = [];

  Map<int, GetContactsListItem> contactsMap = {};

  Map<int, GetUserChatGroupInfoListResultData> chatGroupInfoMap = {};
}

class MobileMessagePageChangeNotifier extends ChangeNotifier {
  MobileMessagePageData data = MobileMessagePageData();

  String _oldGlobalStatusVersion = "";

  Future<void> checkGlobalStatusVersionAndReload(
      String newGlobalStatusVersion) async {
    if (_oldGlobalStatusVersion == newGlobalStatusVersion) {
      return;
    }
    _oldGlobalStatusVersion = newGlobalStatusVersion;
    reload();
  }

  Future<void> reload() async {
    MobileMessagePageData newData = MobileMessagePageData();
    newData.localConversationList =
        await LocalConversationService.listAllLocalConversation();
    {
      List<GetContactsListItem> itemList =
          (await HttpUtils.getContactsList()).data ?? [];
      for (var item in itemList) {
        newData.contactsMap[item.id!] = item;
      }
    }
    List<GetUserChatGroupInfoListResultData> userChatGroupInfoList =
        (await HttpUtils.getUserChatGroupInfoList()).data ?? [];
    newData.chatGroupInfoMap.clear();
    for (var item in userChatGroupInfoList) {
      newData.chatGroupInfoMap[item.id!] = item;
    }
    data = newData;
    notifyListeners();
  }
}

class MobileMessagePage extends StatelessWidget {
  final Logger logger = Logger();

  MobileMessagePage({super.key});

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context) {
          MobileMessagePageChangeNotifier notifier =
              MobileMessagePageChangeNotifier();
          return notifier;
        })
      ],
      child: Consumer3<MobileMessagePageChangeNotifier,
              AppUserDetailChangeNotifier, GlobalStatus>(
          builder: (context, mobileMessagePageChangeNotifier,
              appUserDetailChangeNotifier, globalStatus, child) {
        mobileMessagePageChangeNotifier
            .checkGlobalStatusVersionAndReload(globalStatus.getVersion());
        List<LocalConversation> localConversationList =
            mobileMessagePageChangeNotifier.data.localConversationList;

        var appUserDetail = appUserDetailChangeNotifier.getAppUserDetail();
        return ListView.builder(
            itemCount: localConversationList.length,
            itemBuilder: (ctx, index) {
              int? selfUserId = appUserDetail.id;
              if (selfUserId == null) {
                return const SizedBox(
                  width: double.infinity,
                  height: 0,
                );
              }
              LocalConversation localConversation =
                  localConversationList[index];
              if (localConversation.type ==
                  LocalConversationTypeConstants.group) {
                return Slidable(
                  endActionPane: ActionPane(
                    motion: const ScrollMotion(),
                    children: [
                      SlidableAction(
                        flex: 2,
                        onPressed: (context) async {
                          await deleteLocalConversationAndMessage(
                              localConversation,
                              appUserDetail,
                              mobileMessagePageChangeNotifier);
                        },
                        backgroundColor: Colors.red,
                        foregroundColor: Colors.white,
                        icon: Icons.delete,
                        label: '删除',
                      ),
                    ],
                  ),
                  child: chatGroupMessageItem(localConversation, appUserDetail,
                      mobileMessagePageChangeNotifier),
                );
              } else {
                return Slidable(
                  endActionPane: ActionPane(
                    motion: const ScrollMotion(),
                    children: [
                      SlidableAction(
                        flex: 2,
                        onPressed: (context) async {
                          await deleteLocalConversationAndMessage(
                              localConversation,
                              appUserDetail,
                              mobileMessagePageChangeNotifier);
                        },
                        backgroundColor: Colors.red,
                        foregroundColor: Colors.white,
                        icon: Icons.delete,
                        label: '删除',
                      ),
                    ],
                  ),
                  child: generalMessageItem(localConversation, appUserDetail,
                      mobileMessagePageChangeNotifier),
                );
              }
            });
      }),
    );
  }

  Future<void> onTapMessageItem(
      GetContactsListItem? contacts,
      AppUserDetail? appUserDetail,
      LocalConversation localConversation,
      MobileMessagePageChangeNotifier mobileMessagePageChangeNotifier) async {
    if (localConversation.type == LocalConversationTypeConstants.group) {
      logger.i("localConversation:$localConversation");
      GetUserChatGroupInfoListResultData chatGroupInfo =
          mobileMessagePageChangeNotifier
              .data.chatGroupInfoMap[localConversation.chatGroupId]!;
      await RouteUtils.route2MobileChatPage(MobileChatPageParams(
          currentUserId: appUserDetail?.id!,
          currentUserCode: appUserDetail?.code,
          currentUserNickName: appUserDetail?.nickname,
          currentUserHeadPortrait: appUserDetail?.headPortrait,
          currentUserHeadPortraitStoreType:
              appUserDetail?.headPortraitStoreType,
          localConversation: localConversation,
          chatGroupDetail: chatGroupInfo));
    } else {
      await RouteUtils.route2MobileChatPage(MobileChatPageParams(
          contactUserId: contacts!.id,
          contactUserCode: contacts.code,
          contactUserNickname: contacts.nickname!,
          contactUserHeadPortrait: contacts.headPortrait,
          contactUserHeadPortraitStoreType: contacts.headPortraitStoreType,
          currentUserId: appUserDetail?.id!,
          currentUserCode: appUserDetail?.code,
          currentUserNickName: appUserDetail?.nickname,
          currentUserHeadPortrait: appUserDetail?.headPortrait,
          currentUserHeadPortraitStoreType:
              appUserDetail?.headPortraitStoreType,
          localConversation: localConversation));
    }
    await LocalMessageService.changeAllMsgReadState2Read(localConversation.id!);
    await mobileMessagePageChangeNotifier.reload();
  }

  Widget chatGroupMessageItem(
      LocalConversation localConversation,
      AppUserDetail appUserDetail,
      MobileMessagePageChangeNotifier mobileMessagePageChangeNotifier) {
    int unreadMsgCount = localConversation.unreadMsgCount ?? 0;
    String badgeLabelText = "";
    double badgeOpacity = 1;
    if (unreadMsgCount == 0) {
      badgeOpacity = 0;
    }
    if (unreadMsgCount > 0) {
      badgeLabelText = "$unreadMsgCount";
    }
    if (unreadMsgCount > 99) {
      badgeLabelText = "...";
    }

    DateTime now = DateTime.now();
    DateTime updateTime =
        DateTime.fromMillisecondsSinceEpoch(localConversation.updateTime!);
    String formatUpdateTime =
        "${updateTime.year}-${updateTime.month}-${updateTime.day}";
    if (now.year == updateTime.year &&
        now.month == updateTime.month &&
        now.day == updateTime.day) {
      formatUpdateTime = "${updateTime.hour}:${updateTime.minute}";
    }

    int chatGroupId = localConversation.chatGroupId!;
    GetUserChatGroupInfoListResultData? chatGroupInfo =
        mobileMessagePageChangeNotifier.data.chatGroupInfoMap[chatGroupId];
    List<UserHeadPortraitInfo> userHeadPortraitInfoList = [];
    String chatGroupName = "群聊";
    if (chatGroupInfo != null) {
      userHeadPortraitInfoList =
          (chatGroupInfo.chatGroupUserItemList ?? []).map((item) {
        return UserHeadPortraitInfo.create(
            item.code, item.headPortrait, item.headPortraitStoreType);
      }).toList();
      chatGroupName = chatGroupInfo.name ??
          "群聊(${(chatGroupInfo.chatGroupUserItemList ?? []).length})";
    }
    return GestureDetector(
      onTap: () async {
        await onTapMessageItem(null, appUserDetail, localConversation,
            mobileMessagePageChangeNotifier);
      },
      child: Container(
        padding: const EdgeInsets.only(left: 15, right: 15),
        height: 65,
        child: Row(
          children: [
            Container(
              padding: const EdgeInsets.only(right: 15),
              alignment: Alignment.center,
              child: Badge(
                label: Text(badgeLabelText),
                backgroundColor: Color.fromRGBO(247, 80, 80, badgeOpacity),
                child:
                    ChatGroupHeadPortrait.create(userHeadPortraitInfoList, 45),
              ),
            ),
            Expanded(
                child: Container(
              padding: const EdgeInsets.only(top: 10),
              decoration: const BoxDecoration(
                  border: Border(bottom: BorderSide(color: Colors.black12))),
              alignment: Alignment.centerLeft,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Expanded(
                          child: Text(
                        chatGroupName,
                        style: const TextStyle(
                            fontSize: 16, overflow: TextOverflow.ellipsis),
                      )),
                      Expanded(
                          child: Container(
                        alignment: Alignment.centerRight,
                        child: Text(
                          formatUpdateTime,
                          style: const TextStyle(
                              fontSize: 10,
                              color: Color.fromRGBO(178, 178, 178, 1)),
                        ),
                      )),
                    ],
                  ),
                  const SizedBox(height: 5),
                  Text(
                    StringUtils.defaultIfEmpty(localConversation.newestMsg, ""),
                    overflow: TextOverflow.ellipsis,
                    style: const TextStyle(
                        fontSize: 12, color: Color.fromRGBO(178, 178, 178, 1)),
                  )
                ],
              ),
            ))
          ],
        ),
      ),
    );
  }

  Widget generalMessageItem(
      LocalConversation localConversation,
      AppUserDetail appUserDetail,
      MobileMessagePageChangeNotifier mobileMessagePageChangeNotifier) {
    int? friendId = localConversation.uid1;
    int selfUserId = appUserDetail.id!;
    if (friendId == selfUserId) {
      friendId = localConversation.uid2;
    }
    Map<int, GetContactsListItem> contactsMap =
        mobileMessagePageChangeNotifier.data.contactsMap;
    GetContactsListItem? contacts = contactsMap[friendId];
    int unreadMsgCount = localConversation.unreadMsgCount ?? 0;
    String badgeLabelText = "";
    double badgeOpacity = 1;
    if (unreadMsgCount == 0) {
      badgeOpacity = 0;
    }
    if (unreadMsgCount > 0) {
      badgeLabelText = "$unreadMsgCount";
    }
    if (unreadMsgCount > 99) {
      badgeLabelText = "...";
    }

    DateTime now = DateTime.now();
    DateTime updateTime =
        DateTime.fromMillisecondsSinceEpoch(localConversation.updateTime!);
    String formatUpdateTime =
        "${updateTime.year}-${updateTime.month}-${updateTime.day}";
    if (now.year == updateTime.year &&
        now.month == updateTime.month &&
        now.day == updateTime.day) {
      formatUpdateTime = "${updateTime.hour}:${updateTime.minute}";
    }

    Widget userHeadPortrait = const FlutterLogo(size: 45);
    if (contacts != null) {
      userHeadPortrait = UserHeadPortrait.network(
          size: 45,
          userCode: contacts.code!,
          userHeadPortrait: contacts.headPortrait!,
          userHeadPortraitStoreType: contacts.headPortraitStoreType!);
    }

    return GestureDetector(
      onTap: () async {
        await onTapMessageItem(contacts, appUserDetail, localConversation,
            mobileMessagePageChangeNotifier);
      },
      child: Container(
        padding: const EdgeInsets.only(left: 15, right: 15),
        height: 65,
        child: Row(
          children: [
            Container(
              padding: const EdgeInsets.only(right: 15),
              alignment: Alignment.center,
              child: Badge(
                label: Text(badgeLabelText),
                backgroundColor: Color.fromRGBO(247, 80, 80, badgeOpacity),
                child: userHeadPortrait,
              ),
            ),
            Expanded(
                child: Container(
              padding: const EdgeInsets.only(top: 10),
              decoration: const BoxDecoration(
                  border: Border(bottom: BorderSide(color: Colors.black12))),
              alignment: Alignment.centerLeft,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Expanded(
                          child: Text(
                        StringUtils.defaultIfEmpty(contacts?.nickname, ""),
                        style: const TextStyle(fontSize: 16),
                      )),
                      Expanded(
                          child: Container(
                        alignment: Alignment.centerRight,
                        child: Text(
                          formatUpdateTime,
                          style: const TextStyle(
                              fontSize: 10,
                              color: Color.fromRGBO(178, 178, 178, 1)),
                        ),
                      )),
                    ],
                  ),
                  const SizedBox(height: 5),
                  Text(
                    StringUtils.defaultIfEmpty(localConversation.newestMsg, ""),
                    overflow: TextOverflow.ellipsis,
                    style: const TextStyle(
                        fontSize: 12, color: Color.fromRGBO(178, 178, 178, 1)),
                  )
                ],
              ),
            ))
          ],
        ),
      ),
    );
  }

  Future<void> deleteLocalConversationAndMessage(
      LocalConversation localConversation,
      AppUserDetail appUserDetail,
      MobileMessagePageChangeNotifier mobileMessagePageChangeNotifier) async {
    await LocalConversationService.deleteChatHistoryByConversationID(
        localConversation.id!);
    await mobileMessagePageChangeNotifier.reload();
  }
}
